/**
 * 命理计算控制器
 * 处理命理相关的HTTP请求
 */

const { calculateBazi, analyzeBazi } = require('../services/bazi.service');
const TarotService = require('../services/tarot.service');
const TAROT_CARDS = require('../models/TarotCard');
const { logInfo, logError } = require('../logger');

/**
 * 八字排盘控制器
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
async function getBazi(req, res) {
  try {
    // 从请求体获取参数
    const { birthDate, birthTime, timezone, gender } = req.body;
    
    // 参数验证
    if (!birthDate || !birthTime || timezone === undefined || !gender) {
      return res.status(400).json({
        success: false,
        message: '缺少必要的参数：birthDate, birthTime, timezone, gender'
      });
    }
    
    // 构造完整的ISO时间字符串
    // 注意：前端传来的timezone是一个数值（小时偏移量）
    let isoString;
    if (timezone >= 0) {
      isoString = `${birthDate}T${birthTime}+${timezone.toString().padStart(2, '0')}:00`;
    } else {
      isoString = `${birthDate}T${birthTime}-${Math.abs(timezone).toString().padStart(2, '0')}:00`;
    }
    
    // 创建完整的出生日期时间对象
    const birthDateTime = new Date(isoString);
    
    // 验证日期有效性
    if (isNaN(birthDateTime.getTime())) {
      return res.status(400).json({
        success: false,
        message: '无效的日期或时间格式'
      });
    }
    
    // 记录日志
    logInfo('开始八字排盘计算', { birthDate: birthDateTime.toISOString() });
    
    // 计算八字
    const bazi = calculateBazi(birthDateTime);
    
    // 如果用户已登录，保存记录到数据库
    if (req.user) {
      try {
        const { BaziRecord } = require('../models/BaziRecord');
        
        // 创建输入参数对象
        const inputParams = {
          birthDate,
          birthTime,
          timezone,
          gender
        };
        
        // 创建计算结果对象
        const calculationResult = {
          bazi,
          timestamp: new Date().toISOString()
        };
        
        // 生成计算哈希（基于输入参数的字符串化）
        const crypto = require('crypto');
        const calculationHash = crypto
          .createHash('md5')
          .update(JSON.stringify(inputParams))
          .digest('hex');
        
        // 保存到数据库
        await BaziRecord.create({
          userId: req.user.id,
          calculationHash,
          inputParams,
          calculationResult,
          isFavorite: false
        });
        
        logInfo('八字排盘记录保存成功', { userId: req.user.id });
      } catch (saveError) {
        logError('八字排盘记录保存失败', { error: saveError.message });
        // 不中断主流程，继续返回结果
      }
    }
    
    // 记录日志
    logInfo('八字排盘计算完成');
    logInfo('八字排盘接口调用成功');
    
    // 返回结果
    return res.status(200).json({
      success: true,
      message: '八字排盘成功',
      data: {
        bazi
      }
    });
  } catch (error) {
    // 记录错误日志
    logError('八字排盘接口调用失败', { error: error.message });
    
    // 返回错误响应
    return res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
}

/**
 * 八字分析控制器
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
async function analyzeBaziHandler(req, res) {
  try {
    // 从请求体获取八字数据
    const { bazi } = req.body;
    
    // 参数验证
    if (!bazi) {
      return res.status(400).json({
        success: false,
        message: '缺少必要的参数：bazi'
      });
    }
    
    // 分析八字
    const analysis = analyzeBazi(bazi);
    
    // 记录日志
    logInfo('八字分析接口调用成功');
    
    // 返回结果
    return res.status(200).json({
      success: true,
      message: '八字分析成功',
      data: {
        analysis
      }
    });
  } catch (error) {
    // 记录错误日志
    logError('八字分析接口调用失败', { error: error.message });
    
    // 返回错误响应
    return res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
}

/**
 * 塔罗牌占卜控制器
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
async function getTarotReading(req, res) {
  try {
    // 从请求体获取参数
    const { count } = req.body;
    
    // 默认抽取3张牌
    const cardCount = count || 3;
    
    // 抽取塔罗牌
    const cards = drawCards(cardCount);
    
    // 解读塔罗牌
    const reading = interpretCards(cards);
    
    // 记录日志
    logInfo('塔罗牌占卜接口调用成功');
    
    // 返回结果
    return res.status(200).json({
      success: true,
      message: '塔罗牌占卜成功',
      data: {
        reading
      }
    });
  } catch (error) {
    // 记录错误日志
    logError('塔罗牌占卜接口调用失败', { error: error.message });
    
    // 返回错误响应
    return res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
}

/**
 * 获取所有塔罗牌
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
async function getTarotCards(req, res) {
  try {
    // 记录请求信息
    logInfo('获取所有塔罗牌');
    
    // 返回塔罗牌数据
    res.json({
      success: true,
      message: '塔罗牌数据获取成功',
      data: TAROT_CARDS
    });
    
    // 记录成功日志
    logInfo('塔罗牌数据获取完成');
  } catch (error) {
    // 记录错误日志
    logError('塔罗牌数据获取失败', { error: error.message });
    
    // 返回错误响应
    res.status(500).json({
      success: false,
      message: '塔罗牌数据获取失败',
      error: error.message
    });
  }
}

/**
 * 抽取塔罗牌
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
async function drawTarotCards(req, res) {
  try {
    // 从请求体获取参数
    const { count } = req.body;
    
    // 记录请求信息
    logInfo('开始抽取塔罗牌', { count });
    
    // 调用服务层进行抽牌
    const drawnCards = await TarotService.drawCards(count);
    
    // 返回成功响应
    res.json({
      success: true,
      message: '塔罗牌抽取成功',
      data: drawnCards
    });
    
    // 记录成功日志
    logInfo('塔罗牌抽取完成');
  } catch (error) {
    // 记录错误日志
    logError('塔罗牌抽取失败', { error: error.message });
    
    // 返回错误响应
    res.status(500).json({
      success: false,
      message: '塔罗牌抽取失败',
      error: error.message
    });
  }
}

/**
 * 解读塔罗牌
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
async function interpretTarotCards(req, res) {
  try {
    // 从请求体获取参数
    const { cards } = req.body;
    
    // 记录请求信息
    logInfo('开始解读塔罗牌', { cards: cards.map(c => c.name) });
    
    // 调用服务层进行解读
    const interpretation = await TarotService.interpretCards(cards);
    
    // 返回成功响应
    res.json({
      success: true,
      message: '塔罗牌解读成功',
      data: interpretation
    });
    
    // 记录成功日志
    logInfo('塔罗牌解读完成');
  } catch (error) {
    // 记录错误日志
    logError('塔罗牌解读失败', { error: error.message });
    
    // 返回错误响应
    res.status(500).json({
      success: false,
      message: '塔罗牌解读失败',
      error: error.message
    });
  }
}

/**
 * 保存塔罗牌占卜记录
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
const saveTarotReading = async (req, res) => {
  try {
    // 获取请求参数
    const { userId, spreadType, question, category, cardsDrawn, interpretation } = req.body;
    
    // 参数验证
    if (!userId || !spreadType || !cardsDrawn || !interpretation) {
      return res.status(400).json({
        success: false,
        error: '缺少必要的参数'
      });
    }
    
    // 调用服务保存记录
    const TarotService = require('../services/tarot.service');
    const savedReading = await TarotService.saveReading(
      userId, 
      spreadType, 
      question, 
      category,
      cardsDrawn, 
      interpretation
    );
    
    // 返回成功响应
    res.status(201).json({
      success: true,
      data: savedReading,
      message: '占卜记录保存成功'
    });
  } catch (error) {
    logger.error('保存塔罗牌占卜记录失败', { 
      error: error.message,
      userId: req.body.userId,
      spreadType: req.body.spreadType
    });
    
    res.status(500).json({
      success: false,
      error: '保存占卜记录失败'
    });
  }
};

/**
 * 收藏塔罗牌占卜记录
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
const favoriteTarotReading = async (req, res) => {
  try {
    // 获取请求参数
    const { readingId } = req.body;
    
    // 参数验证
    if (!readingId) {
      return res.status(400).json({
        success: false,
        error: '缺少记录ID参数'
      });
    }
    
    // 调用服务收藏记录
    const TarotService = require('../services/tarot.service');
    const favoritedReading = await TarotService.favoriteReading(readingId);
    
    // 返回成功响应
    res.status(200).json({
      success: true,
      data: favoritedReading,
      message: '占卜记录收藏成功'
    });
  } catch (error) {
    logger.error('收藏塔罗牌占卜记录失败', { 
      error: error.message,
      readingId: req.body.readingId
    });
    
    res.status(500).json({
      success: false,
      error: '收藏占卜记录失败'
    });
  }
};

/**
 * 获取用户的塔罗牌占卜记录
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
const getUserTarotReadings = async (req, res) => {
  try {
    // 获取用户ID参数
    const { userId } = req.params;
    
    // 参数验证
    if (!userId) {
      return res.status(400).json({
        success: false,
        error: '缺少用户ID参数'
      });
    }
    
    // 调用服务获取记录
    const TarotService = require('../services/tarot.service');
    const readings = await TarotService.getUserReadings(userId);
    
    // 返回成功响应
    res.status(200).json({
      success: true,
      data: readings,
      message: '获取占卜记录成功'
    });
  } catch (error) {
    logger.error('获取用户塔罗牌占卜记录失败', { 
      error: error.message,
      userId: req.params.userId
    });
    
    res.status(500).json({
      success: false,
      error: '获取占卜记录失败'
    });
  }
};

/**
 * 获取用户收藏的塔罗牌占卜记录
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
const getSavedTarotReadings = async (req, res) => {
  try {
    // 获取用户ID参数
    const { userId } = req.params;
    
    // 参数验证
    if (!userId) {
      return res.status(400).json({
        success: false,
        error: '缺少用户ID参数'
      });
    }
    
    // 调用服务获取收藏记录
    const TarotService = require('../services/tarot.service');
    const readings = await TarotService.getSavedReadings(userId);
    
    // 返回成功响应
    res.status(200).json({
      success: true,
      data: readings,
      message: '获取收藏记录成功'
    });
  } catch (error) {
    logger.error('获取用户收藏的塔罗牌占卜记录失败', { 
      error: error.message,
      userId: req.params.userId
    });
    
    res.status(500).json({
      success: false,
      error: '获取收藏记录失败'
    });
  }
};

/**
 * 获取今日推荐牌阵
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
const getDailyRecommendedSpread = async (req, res) => {
  try {
    // 获取用户ID参数
    const { userId } = req.params;
    
    // 参数验证
    if (!userId) {
      return res.status(400).json({
        success: false,
        error: '缺少用户ID参数'
      });
    }
    
    // 调用服务获取推荐牌阵
    const TarotService = require('../services/tarot.service');
    const recommendation = await TarotService.getDailyRecommendedSpread(userId);
    
    // 返回成功响应
    res.status(200).json({
      success: true,
      data: recommendation,
      message: '获取今日推荐牌阵成功'
    });
  } catch (error) {
    logger.error('获取今日推荐牌阵失败', { 
      error: error.message,
      userId: req.params.userId
    });
    
    res.status(500).json({
      success: false,
      error: '获取推荐牌阵失败'
    });
  }
};

module.exports = {
  // 八字相关控制器
  calculateBazi: getBazi,
  
  // 塔罗牌相关控制器
  getTarotCards,
  drawTarotCards,
  interpretTarotCards,
  saveTarotReading,
  favoriteTarotReading,
  getUserTarotReadings,
  getSavedTarotReadings,
  getDailyRecommendedSpread
};